Skip to content

Extract Maven repo interaction logic for JVM ecosystems reuse#14721

Open
AbhishekBhaskar wants to merge 5 commits intomainfrom
abhishekbhaskar/extract-maven-repo-interaction-logic
Open

Extract Maven repo interaction logic for JVM ecosystems reuse#14721
AbhishekBhaskar wants to merge 5 commits intomainfrom
abhishekbhaskar/extract-maven-repo-interaction-logic

Conversation

@AbhishekBhaskar
Copy link
Copy Markdown
Contributor

What are you trying to accomplish?

Extracts Maven repository interaction logic from Maven::Package::PackageDetailsFetcher into a new abstract base class Maven::Shared::SharedMavenRepositoryClient, enabling SBT (and other JVM ecosystems) to reuse Maven repository resolution without duplicating code.
SBT resolves dependencies from Maven repositories using the same maven-metadata.xml format, URL conventions, and auth patterns as Maven. Rather than duplicating ~300 lines of repository client logic in the SBT ecosystem, we extract it into a shared abstract class that both Maven and SBT can inherit from.

Changes:
New file: shared_maven_repository_client.rb

  • Abstract base class (~340 lines) under Dependabot::Maven::Shared
  • Extracted logic: URL construction (dependency_parts, dependency_base_url, dependency_metadata_url, dependency_files_url), metadata fetching (XML + HTML), version extraction, response checking, forbidden URL tracking, released? checks, credential/auth header handling, and per-repository metadata caching
  • Defines 3 abstract methods subclasses must implement: dependency, credentials, repositories
  • Provides overridable hooks: dependency_parts (for non-standard naming), central_repo_url (for credential-based overrides)

Modified file: package_details_fetcher.rb

  • Now inherits from SharedMavenRepositoryClient (was standalone class)
  • Reduced from ~470 lines to ~220 lines
  • Retains only Maven-specific logic:
    - fetch / releases — package details orchestration
    - released? — delegates to parent via super
    - repositories (override) — assembles credential repos + POM-declared repos
    - central_repo_url (override) — delegates to RepositoriesFinder
    - versions / versions_details_from_xml / versions_details_hash_from_html — version list assembly
    - repository_finder / pom_repository_details / pom — Maven POM helpers

Anything you want to highlight for special attention from reviewers?

Method What SBT implements
dependency attr_reader — same as Maven, no custom logic needed
credentials attr_reader — same as Maven, no custom logic needed
repositories SBT-specific: assemble repos from resolvers in build.sbt + credential repos via inherited credentials_repository_details

How will you know you've accomplished your goal?

If all the existing unit tests pass without failures.

Checklist

  • I have run the complete test suite to ensure all tests and linters pass.
  • I have thoroughly tested my code changes to ensure they work as expected, including adding additional tests for new functionality.
  • I have written clear and descriptive commit messages.
  • I have provided a detailed description of the changes in the pull request, including the problem it addresses, how it fixes the problem, and any relevant details about the implementation.
  • I have ensured that the code is well-documented and easy to understand.

@AbhishekBhaskar AbhishekBhaskar self-assigned this Apr 15, 2026
@github-actions github-actions bot added the L: java:maven Maven packages via Maven label Apr 15, 2026
@AbhishekBhaskar AbhishekBhaskar changed the title [WIP] Extract Maven repo interaction logic for JVM ecosystems reuse Extract Maven repo interaction logic for JVM ecosystems reuse Apr 15, 2026
@AbhishekBhaskar AbhishekBhaskar marked this pull request as ready for review April 15, 2026 18:10
@AbhishekBhaskar AbhishekBhaskar requested a review from a team as a code owner April 15, 2026 18:10
Copilot AI review requested due to automatic review settings April 15, 2026 18:10
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Refactors Maven repository interaction logic into a reusable shared client so other JVM ecosystems (e.g., SBT) can leverage the same Maven repository resolution behavior without duplicating code.

Changes:

  • Introduces an abstract SharedMavenRepositoryClient with shared URL construction, metadata fetching/parsing, auth header handling, and caching.
  • Updates Maven::Package::PackageDetailsFetcher to inherit from the new shared client and retain only Maven-specific orchestration/repository assembly.
  • Adds a comprehensive spec suite for the shared client behavior.
Show a summary per file
File Description
maven/lib/dependabot/maven/shared/shared_maven_repository_client.rb New shared abstract base class encapsulating Maven repository interaction logic for reuse across JVM ecosystems.
maven/lib/dependabot/maven/package/package_details_fetcher.rb Refactors Maven package details fetching to inherit shared repository logic and keep Maven-specific behavior.
maven/spec/dependabot/maven/shared/shared_maven_repository_client_spec.rb Adds unit tests for shared repository client behavior (URL building, metadata parsing, caching, auth/forbidden tracking).

Copilot's findings

  • Files reviewed: 3/3 changed files
  • Comments generated: 3

Comment thread maven/lib/dependabot/maven/shared/shared_maven_repository_client.rb
Comment thread maven/lib/dependabot/maven/shared/shared_maven_repository_client.rb
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Extracts Maven repository interaction logic into a shared, abstract client so Maven (and other JVM ecosystems like SBT) can reuse Maven-repository URL construction, metadata fetching/parsing, auth header handling, and caching without duplicating code.

Changes:

  • Added SharedMavenRepositoryClient abstract base class under Dependabot::Maven::Shared with shared Maven-repo HTTP and parsing logic.
  • Updated Maven PackageDetailsFetcher to inherit from the shared client and keep only Maven-specific orchestration/repository assembly.
  • Added a dedicated spec suite for the shared client behaviors (URL construction, parsing, response handling, caching).
Show a summary per file
File Description
maven/lib/dependabot/maven/shared/shared_maven_repository_client.rb Introduces shared Maven repository client with URL construction, registry calls, forbidden URL tracking, and metadata/release caching.
maven/lib/dependabot/maven/package/package_details_fetcher.rb Refactors Maven package details fetcher to inherit shared client and override repository assembly + central repo selection.
maven/spec/dependabot/maven/shared/shared_maven_repository_client_spec.rb Adds coverage for the extracted shared client logic (URLs, parsing, error/forbidden handling, caching).

Copilot's findings

  • Files reviewed: 3/3 changed files
  • Comments generated: 2

# Uses the Maven RepositoriesFinder's central URL to support credential-based overrides.
sig { override.returns(String) }
def central_repo_url
repository_finder.central_repo_url
Copy link

Copilot AI Apr 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

central_repo_url can come from RepositoriesFinder#central_repo_url, which returns the raw credential URL when replaces-base is set (and that value may include a trailing /). Most repository URLs are normalized without trailing slashes (e.g., credentials_repository_details), so leaving this unnormalized can cause duplicate repo entries and can break central-repo comparisons in the shared client (e.g., central_repo_urls.include?(repository_url) in check_response / handle_registry_error). Consider normalizing here (strip trailing slashes) before returning.

Suggested change
repository_finder.central_repo_url
repository_finder.central_repo_url.sub(%r{/+\z}, "")

Copilot uses AI. Check for mistakes.
# Both HTTP and HTTPS variants of the central repo URL, for comparison.
sig { returns(T::Array[String]) }
def central_repo_urls
central_url_without_protocol = central_repo_url.gsub(%r{^.*://}, "")
Copy link

Copilot AI Apr 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

central_repo_urls strips the protocol but does not normalize trailing slashes. If central_repo_url is overridden from credentials (e.g., replaces-base) and includes a trailing /, comparisons like central_repo_urls.include?(repository_url) may fail because repository URLs are typically normalized without trailing slashes, which can lead to incorrect forbidden URL tracking and error handling. Normalize the central URL here (e.g., strip trailing slashes) before building the http/https variants.

Suggested change
central_url_without_protocol = central_repo_url.gsub(%r{^.*://}, "")
central_url_without_protocol = central_repo_url
.gsub(%r{^.*://}, "")
.gsub(%r{/+$}, "")

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

L: java:maven Maven packages via Maven

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants